var crypto  = require("crypto"),
    xml = require("node-xml"),
    util = require('../util'),
    vpn = require('./vpn'),
    subscribeService = require('./subscribe'),
    registerService =  require('./register'),
    adminService = require('./admin'),
    Promise  = require('bluebird'),
    https = require('https'),
    config = require('../util').config;

function isLegel(signature, timestamp, nonce, token) {
  var array  = [];
  array[0]   = timestamp;
  array[1]   = nonce;
  array[2]   = token;
  array.sort();
  var hasher = crypto.createHash("sha1");
  var msg    = array[0] + array[1] + array[2];
  hasher.update(msg);
  msg    = hasher.digest('hex');
  if (msg == signature) {
    return true;
  } else {
    return false;
  }
}

/**
 * 处理微信消息
 * @param {String} data xml格式的微信消息
 */
function processMessage(data) {
  console.log(data);
  return new Promise(function (resolve, reject) {
    var message  = {};
    var tempName = "";

    // 解析并处理XML消息
    var parse    = new xml.SaxParser(function (cb) {

      // 节点开始事件
      cb.onStartElementNS(function (elem, attra, prefix, uri, namespaces) {
        tempName = elem;
      });

      // 文本事件
      cb.onCharacters(function (chars) {

        // ignore '/n    ', values which start from the end of previous elem and to the start of the will comming elem
        //    </A>
        //    <B>
        if (!chars.match(/^\n\s*$/)) {
          message[tempName] = chars.replace(/^\n\s*/g, "");
        }
      });

      // CDATA事件
      cb.onCdata(function (cdata) {
        message[tempName] = cdata;
      });

      // 节点结束事件
      cb.onEndElementNS(function (elem, prefix, uri) {
        tempName = "";
      });

      // 文档结束事件
      cb.onEndDocument(function () {
        tempName = "";

        // 事件推送处理
        if ('event' == message.MsgType) {
          if ('subscribe' == message.Event) {
            if (message.EventKey && message.EventKey.indexOf('qrscene_') == 0) {

              // 扫描二维码关注
              resolve(subscribeService.subscribeByScan(message));
            } else {

              // 直接关注
              resolve(subscribeService.subscribe(message));
            }
          } else if ('unsubscribe' == message.Event) {

            // 取消关注
          } else if ('SCAN' == message.Event) {

            // 已关注用户扫描二维码
          } else if ('LOCATION' == message.Event) {

            // 上报地理位置事件
          } else if ('CLICK' == message.Event) {

            // 点击菜单拉取消息时的事件推送
           resolve(vpn.getVpnMsg(message));
          } else if ('VIEW' == message.Event) {

            // 点击菜单跳转链接时的事件推送
          }
        } else if ('text' == message.MsgType) {

          // 接收文本消息
          resolve(textMsgProcesser(message));
        } else if ('image' == message.MsgType) {

          // 接收图片消息
        } else if ('voice' == message.MsgType) {

          // 接收语音消息
        } else if ('video' == message.MsgType) {

          // 接收视频消息
        } else if ('shortvideo' == message.MsgType) {

          // 接收小视频消息
        } else if ('location' == message.MsgType) {

          // 接收地理位置消息
        } else if ('link' == message.MsgType) {

          // 接收链接消息
        }
        resolve(message);
      });
    });
    parse.parseString(data);
  });
}

function textMsgProcesser (msg) {

  // vpn添加/变更
  if (adminService.isAdminVpnMsg(msg)) {
    return adminService.changeVpn(msg);
  }

  // 默认消息, 注册消息
  return registerService.register(msg);
}

function createMenu() {
  return util.weixin.getAccessToken().then(function(assToken) {
    var api = '/cgi-bin/menu/create?access_token=' + assToken.access_token;
    var jsonMenu = util.config.menu;
    var options = {
      hostname: 'api.weixin.qq.com',
      port    : 443,
      path    : api,
      method  : 'POST',
      headers : {
        'Content-Type': 'application/json; charset=UTF-8'
        // 'Content-Length': reqJsonData.length
      }
    };

    var req = https.request(options, function (res) {
      var result = '';
      res.on('data', function (chunk) {
        result += chunk;
      });
      res.on('end', function () {
        return Promise.resolve(result);
      });
    });
    req.on('error', function (err) {
      return Promise.reject(err);
    });
    req.write(jsonMenu);
    req.end();
  });
}

module.exports = {
  isLegel: isLegel,
  processMessage: processMessage,
  createMenu: createMenu
};